# -*- encoding: utf-8 -*-
"""
File Name: dedicated_line_monitor
Description:
Author : 'lirui'
date: 2024/1/26
Contact: marjey_lee@163.com
Change Activity:
2024/1/26:
"""
import time
from threading import Thread

import ll
from projects.monitoring.branch_dedicated_line_monitor.services.cli_parse import CliParser
from projects.monitoring.branch_dedicated_line_monitor.utils.load_cmdb_info import load_branch_dedicated_info_from_cmdb
from projects.monitoring.branch_dedicated_line_monitor.utils.router_connection import build_router_connection_mapping
from projects.monitoring.common.utils.redis_problem_publishers_manager import RedisProblemsPublishersManager

ll.get_logger().error(f'This file is not in use.')


class BranchDedicatedLineMonitor(Thread):
    def __init__(self):
        super().__init__()
        self.results = {}
        self.router_connection_mapping = build_router_connection_mapping()
        self.health_check = 1

    def run(self):
        ll.get_logger().info('Start monitoring branch dedicated line.')
        while True:
            try:
                self()
                self.health_check = 1
            except Exception as e:
                ll.get_logger().error(e)
                self.health_check = 0
            time.sleep(30)

    def format_results(self, normal_ip_lst, error_ip_lst):
        """

        Args:
            normal_ip_lst:
            error_ip_lst:

        Returns:

        """
        for ip in normal_ip_lst:
            self.results[ip] = 1
        for ip in error_ip_lst:
            self.results[ip] = 0

    def __call__(self):
        """
        monitor dedicated line
        """
        ll.get_logger().info('Start monitor branch dedicated line.')
        check_res = {}
        cmd = 'display  bgp vpnv4 vpn-instance FDBANK peer'
        error_ip_lst = []
        normal_ip_lst = []
        cmdb_data = load_branch_dedicated_info_from_cmdb()
        try:
            for name, connection in self.router_connection_mapping.items():
                res = connection.send_command(
                    cmd,
                    read_timeout=20
                )
                normal_ips, error_ips = CliParser(res)()
                assert (len(normal_ips) > 0 or len(error_ips) > 0)
                error_ip_lst = error_ips + error_ip_lst
                normal_ip_lst = normal_ip_lst + normal_ips
                for ip in error_ip_lst:
                    if ip in ['10.5.157.10']:
                        continue
                    if ip in cmdb_data:
                        check_res[ip] = cmdb_data[ip]
                    else:
                        check_res[ip] = {
                            'branch': '',
                            'ip': ip,
                        }
                    check_res[ip]['router_ip'] = connection.host
            self.format_results(normal_ip_lst, error_ip_lst)
            self._send_problems_to_redis(check_res)
        except Exception as e:
            ll.get_logger().error(e)
            self.health_check = 0
            self.disconnection()
            self.router_connection_mapping = build_router_connection_mapping()

    @staticmethod
    def _send_problems_to_redis(problems):
        """
        send problems to redis.
        Args:
            problems:

        Returns:

        """
        RedisProblemsPublishersManager.publish(
            key='branch_dedicated_line_monitor',
            content=problems
        )

    def disconnection(self):
        try:
            for router, v in self.router_connection_mapping:
                v.disconnect()
        except Exception as e:
            ll.get_logger().error(e)

    @staticmethod
    def _check_connection(connection):
        if connection is None:
            return False
        try:
            output = connection.send_command(
                'ping  -c 1 127.0.0.1',
                read_timeout=30,
            )
            if 'received' in output:
                return True
            return False
        except Exception as e:
            ll.get_logger().error(e)
            return False


def _main():
    monitor = BranchDedicatedLineMonitor()
    monitor()


if __name__ == '__main__':
    _main()
